tempdimaund@fined newdimentempdima tempdimbund@fined newdimentempdimb tempcntaund@fined newcounttempcnta tempcntbund@fined newcounttempcntb tempboxaund@fined newboxtempboxa
tempa<#4#>box<#4#>@boxa
@boxb
@maxtries=10
@usebox
@hi @hi=67108863
<#521#><#521#>
@catcode
S H A P E P A R . S T Y -- Instructions
@restog<#692#>@ntries@ntries
@dscale@dscale @tottext@tottext<#692#>
@pd
@spec<#693#>i<#693#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#696#>plusm@ <#696#>
@dscale@
@checkspec@spec
@restog<#715#>@ntries@ntries
@dscale@dscale @tottext@tottext<#715#>
@pd
@spec<#716#>t<#716#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#719#>plusm@ <#719#>
@dscale@
@checkspec@spec
SPMquot;). @usebox
@restog<#738#>@ntries@ntries
@dscale@dscale @tottext@tottext<#738#>
@pd
@spec<#739#>:<#739#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#742#>plusm@ <#742#>
@dscale@
@checkspec@spec
@restog<#761#>@ntries@ntries
@dscale@dscale @tottext@tottext<#761#>
@pd
@spec<#762#>e<#762#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#765#>plusm@ <#765#>
@dscale@
@checkspec@spec
These macros work for both LaTeX and plain TeX. For LaTeX, specify
...shapepar...], or for either,
The command
@restog<#784#>@ntries@ntries
@dscale@dscale @tottext@tottext<#784#>
@pd
@spec<#785#>s<#785#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#788#>plusm@ <#788#>
@dscale@
@checkspec@spec
@restog<#807#>@ntries@ntries
@dscale@dscale @tottext@tottext<#807#>
@pd
@spec<#808#>;SPMlt;shape_spec;SPMgt;<#808#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#811#>plusm@ <#811#>
@dscale@
@checkspec@spec
The syntax rules for ;SPMlt;shape_spec;SPMgt; are very specific, and must be followed closely. (In these rules, <#284#> <#284#> mean explicit braces, [ ] denote optional parts, ;SPMlt; ;SPMgt; surround a keyword that is defined (perhaps loosely), and | means ;SPMquot;or;SPMquot;; do not type [ ] ;SPMlt; ;SPMgt; or |, only <#285#> <#285#>.)
;SPMlt;shape_spec;SPMgt; = <#286#>;SPMlt;h_center;SPMgt;<#286#> ;SPMlt;lines;SPMgt;
;SPMlt;lines;SPMgt; = ;SPMlt;line_spec;SPMgt; [
;SPMlt;lines;SPMgt;]
That is, the shape is specified as a single number in braces, followed
by the specifications for the lines, with the lines separated by
. The
final paragraph will have its ;SPMlt;h_center;SPMgt; position centered on the page.
;SPMlt;h_center;SPMgt; is a number (like 10.5) of arbitrary units; whatever units
are used for lengths and positions in the ;SPMlt;lines;SPMgt;, they just need to be
consistent.
The lines in the spec are not lines of text; nor are they the lines that you would use to draw the shape itself. They are horizontal scans across the shape at irregular intervals. Curved shapes need many scan lines for accurate rendering while simple shapes need few. Draw a shape on paper, then draw a series of horizontal lines across the shape, including lines that just touch the top and the bottom of the figure. Each line crosses over pieces of the figure in some region. These intersections of line and figure define a ;SPMlt;line_spec;SPMgt;.
;SPMlt;line_spec;SPMgt; = <#287#>;SPMlt;v_pos;SPMgt;<#287#> ;SPMlt;segment;SPMgt; [ other ;SPMlt;segment;SPMgt;s ]
The ;SPMlt;v_pos;SPMgt; is the vertical position of the line. Each ;SPMlt;line_spec;SPMgt; must have a position greater than or equal to that of the previous line, and with all ;SPMlt;v_pos;SPMgt; ;SPMgt; -1000. Position is measured from top to bottom, and always moving down. Each ;SPMlt;segment;SPMgt; represents a region where text will go in the final paragraph; it is the segment of the horizontal scan line that overlaps the body of the figure. There are five types of segment:
;SPMlt;segment;SPMgt; = t<#288#>pos<#288#><#289#>len<#289#> | b<#290#>pos<#290#> | e<#291#>pos<#291#> | s | j
b<#292#>pos<#292#> begin text at a point at horizontal position pos e<#293#>pos<#293#> end text at a point at horizontal position pos t<#294#>pos<#294#><#295#>len<#295#> make a block of text at position pos with length len s split text (begin whitespace) j join two text blocks (end a gap)
The most common type of segment is t (text). The other types are degenerate in that they are single points rather than finite segments. Types s and j have no explicit position, but they must appear between text segments, and those texts should abut; e.g., t<#296#>3<#296#><#297#>2<#297#>st<#298#>5<#298#><#299#>4<#299#> (text from 3 to 5 and text from 5 to 9).
Let's jump right into a simple example, and the meanings will be clearer. A ;SPMquot;diamond;SPMquot; shape can have the four vertices:
(x=1,y=0) . +---;SPMgt; x ! (0,1) . . (2,1) ! V y . (1,2
This shape can be exactly specified by just three scan lines passing through the vertices. The specification is:
<#300#>1<#300#>
<#303#>1<#303#>t<#304#>0<#304#><#305#>2<#305#>
<#306#>2<#306#>e<#307#>1<#307#> text block ends at point y=2, x=1
Other specification lines, like
<#308#>1.5<#308#>t<#309#>0.5<#309#><#310#>1<#310#>
could be inserted, but would make no difference--the shape is interpolated linearly between scan lines.
Every block of text must start with a b specifier and end with an e spec. on some line below. Every segment specified by t must have a length greater than zero. If two blocks of text merge to form one (like at the top of a heart shape) there should be a j spec at the point of junction. If one block bifurcates (like at the top of a hole in a doughnut) there should be an s spec.
Thus, the first line for any valid shape description must consist of only b segment discriptors; the last line can only have e type discriptors. Although the definition of the units is arbitrary, the numbers should range in magnitude from ~.1 - 100 to avoid numeric overflows and underflows.
If there are errors in the format of the specification,
@restog<#830#>@ntries@ntries
@dscale@dscale @tottext@tottext<#830#>
@pd
@spec<#831#>m<#831#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#834#>plusm@ <#834#>
@dscale@
@checkspec@spec
Shaped Paragraph Error: Error in specification. Check carefully!
At this point you may as well type x or e, as there is very little chance that TeX will continue successfully. You might also get one of TeX's regular error messages, like
Illegal unit of measue (pt inserted). or Missing number, treated as zero.
or you might get no error message at all, just ridiculous formatting. Check shape syntax carefully against the rules and the examples before running them through TeX.
What to do if the figure does not start at a point--if it has a flat top? It can start at a single point, but have the next scan line at the same vertical position! A square paragraph is specified by:
<#311#>1<#311#>
<#314#>0<#314#>t<#315#>0<#315#><#316#>2<#316#>
<#317#>2<#317#>t<#318#>0<#318#><#319#>2<#319#>
<#320#>2<#320#>e<#321#>1<#321#>
Both
@restog<#853#>@ntries@ntries
@dscale@dscale @tottext@tottext<#853#>
@pd
@spec<#854#><#867#>1<#867#><#868#>0<#868#>b<#869#>1<#869#>
<#870#>1<#870#>t<#871#>0<#871#><#872#>2<#872#>
<#873#>2<#873#>e<#874#>1<#874#><#854#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#857#>plusm@ <#857#>
@dscale@
@checkspec@spec
nd
@restog<#884#>@ntries@ntries
@dscale@dscale @tottext@tottext<#884#>
@pd
@spec<#885#><#894#>1<#894#><#895#>0<#895#>b<#896#>0<#896#>
<#897#>0<#897#>t<#898#>0<#898#><#899#>2<#899#>
<#900#>2<#900#>t<#901#>0<#901#><#902#>2<#902#>
<#903#>2<#903#>e<#904#>1<#904#><#885#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#888#>plusm@ <#888#>
@dscale@
@checkspec@spec
re defined above as paragraphs with these shapes.
Now let's get more ambitious. A heart shape must have two simultaneous beginnings, a short stretch of separate text, ending with a join, whereafter there is just one stretch of text leading to the final bottom point. This shape has many scan lines so that the smooth flowing curves are preserved.
Look at <#917#>20<#917#><#918#>0<#918#>b<#919#>13.32<#919#>b<#920#>26.68<#920#>
<#921#>.14<#921#>t<#922#>10.12<#922#><#923#>4.42<#923#>t<#924#>25.46<#924#><#925#>4.42<#925#>
<#926#>.7<#926#>t<#927#>9.14<#927#><#928#>7.16<#928#>t<#929#>23.7<#929#><#930#>7.16<#930#>
<#931#>1.4<#931#>t<#932#>8.4<#932#><#933#>9.02<#933#>t<#934#>22.58<#934#><#935#>9.02<#935#>
<#936#>2.1<#936#>t<#937#>7.82<#937#><#938#>10.42<#938#>t<#939#>21.76<#939#><#940#>10.42<#940#>
<#941#>2.8<#941#>t<#942#>7.36<#942#><#943#>11.58<#943#>t<#944#>21.06<#944#><#945#>11.58<#945#>
<#946#>3.5<#946#>t<#947#>6.98<#947#><#948#>12.56<#948#>t<#949#>20.46<#949#><#950#>12.56<#950#>
<#951#>4.2<#951#>t<#952#>6.68<#952#><#953#>13.32<#953#>jt<#954#>20<#954#><#955#>13.32<#955#>
<#956#>4.9<#956#>t<#957#>6.48<#957#><#958#>27.04<#958#>
<#959#>5.6<#959#>t<#960#>6.34<#960#><#961#>27.32<#961#>
<#962#>6.3<#962#>t<#963#>6.28<#963#><#964#>27.44<#964#>
<#965#>7<#965#>t<#966#>6.26<#966#><#967#>27.48<#967#>
<#968#>7.7<#968#>t<#969#>6.27<#969#><#970#>27.46<#970#>
<#971#>8.4<#971#>t<#972#>6.32<#972#><#973#>27.36<#973#>
<#974#>9.1<#974#>t<#975#>6.4<#975#><#976#>27.2<#976#>
<#977#>9.8<#977#>t<#978#>6.52<#978#><#979#>26.96<#979#>
<#980#>10.5<#980#>t<#981#>6.68<#981#><#982#>26.64<#982#>
<#983#>11.9<#983#>t<#984#>7.12<#984#><#985#>25.76<#985#>
<#986#>13.3<#986#>t<#987#>7.72<#987#><#988#>24.56<#988#>
<#989#>14.7<#989#>t<#990#>8.51<#990#><#991#>22.98<#991#>
<#992#>16.1<#992#>t<#993#>9.5<#993#><#994#>21<#994#>
<#995#>17.5<#995#>t<#996#>10.69<#996#><#997#>18.62<#997#>
<#998#>18.9<#998#>t<#999#>12.08<#999#><#1000#>15.84<#1000#>
<#1001#>20.3<#1001#>t<#1002#>13.7<#1002#><#1003#>12.6<#1003#>
<#1004#>21.7<#1004#>t<#1005#>15.62<#1005#><#1006#>8.76<#1006#>
<#1007#>22.4<#1007#>t<#1008#>16.7<#1008#><#1009#>6.6<#1009#>
<#1010#>23.1<#1010#>t<#1011#>17.87<#1011#><#1012#>4.26<#1012#>
<#1013#>24.6<#1013#>e<#1014#>20<#1014#>and find the two b specifiers at the beginning; find
the j a few lines below. Notice that above the j there are two segments
per line, but only one below it; the text to the left and right of the
join meet at the join point: 20. I drew this heart freehand, and measured
lengths from the sketch, so you should be able to do better!
Text can have holes. For example, a doughnut-shape would have a b on the first line, followed by some lines with a single t, then a line with t s t at the start of the hole. The hole is represented by lines with two t specs--the gap between them is the hole. A line with t j t ends the hole. There are more lines with single t, and then an e line to end with. Our final example is a nut. Not a doughnut, but a hex-nut (for a machine screw) -- a regular hexagon with a circular hole in the center. The hexagon is flat on top and bottom so the specification begins and ends like the square shape. The circle is rendered as a 24-gon, beginning with a split (s) of the surrounding text and ending with a join (j). If the spacing of the scan lines looks odd, it is because the hexagon alone would need few scans, but the circle needs many; the points on the circle are at 15 degree intervals.
@restog<#1016#>@ntries@ntries
@dscale@dscale @tottext@tottext<#1016#>
@pd
@spec<#1017#>c<#1017#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#1020#>plusm@ <#1020#>
@dscale@
@checkspec@spec
@restog<#1039#>@ntries@ntries
@dscale@dscale @tottext@tottext<#1039#>
@pd
@spec<#1040#><#1053#>20<#1053#><#1054#>0<#1054#>b<#1055#>13.32<#1055#>b<#1056#>26.68<#1056#>
<#1057#>.14<#1057#>t<#1058#>10.12<#1058#><#1059#>4.42<#1059#>t<#1060#>25.46<#1060#><#1061#>4.42<#1061#>
<#1062#>.7<#1062#>t<#1063#>9.14<#1063#><#1064#>7.16<#1064#>t<#1065#>23.7<#1065#><#1066#>7.16<#1066#>
<#1067#>1.4<#1067#>t<#1068#>8.4<#1068#><#1069#>9.02<#1069#>t<#1070#>22.58<#1070#><#1071#>9.02<#1071#>
<#1072#>2.1<#1072#>t<#1073#>7.82<#1073#><#1074#>10.42<#1074#>t<#1075#>21.76<#1075#><#1076#>10.42<#1076#>
<#1077#>2.8<#1077#>t<#1078#>7.36<#1078#><#1079#>11.58<#1079#>t<#1080#>21.06<#1080#><#1081#>11.58<#1081#>
<#1082#>3.5<#1082#>t<#1083#>6.98<#1083#><#1084#>12.56<#1084#>t<#1085#>20.46<#1085#><#1086#>12.56<#1086#>
<#1087#>4.2<#1087#>t<#1088#>6.68<#1088#><#1089#>13.32<#1089#>jt<#1090#>20<#1090#><#1091#>13.32<#1091#>
<#1092#>4.9<#1092#>t<#1093#>6.48<#1093#><#1094#>27.04<#1094#>
<#1095#>5.6<#1095#>t<#1096#>6.34<#1096#><#1097#>27.32<#1097#>
<#1098#>6.3<#1098#>t<#1099#>6.28<#1099#><#1100#>27.44<#1100#>
<#1101#>7<#1101#>t<#1102#>6.26<#1102#><#1103#>27.48<#1103#>
<#1104#>7.7<#1104#>t<#1105#>6.27<#1105#><#1106#>27.46<#1106#>
<#1107#>8.4<#1107#>t<#1108#>6.32<#1108#><#1109#>27.36<#1109#>
<#1110#>9.1<#1110#>t<#1111#>6.4<#1111#><#1112#>27.2<#1112#>
<#1113#>9.8<#1113#>t<#1114#>6.52<#1114#><#1115#>26.96<#1115#>
<#1116#>10.5<#1116#>t<#1117#>6.68<#1117#><#1118#>26.64<#1118#>
<#1119#>11.9<#1119#>t<#1120#>7.12<#1120#><#1121#>25.76<#1121#>
<#1122#>13.3<#1122#>t<#1123#>7.72<#1123#><#1124#>24.56<#1124#>
<#1125#>14.7<#1125#>t<#1126#>8.51<#1126#><#1127#>22.98<#1127#>
<#1128#>16.1<#1128#>t<#1129#>9.5<#1129#><#1130#>21<#1130#>
<#1131#>17.5<#1131#>t<#1132#>10.69<#1132#><#1133#>18.62<#1133#>
<#1134#>18.9<#1134#>t<#1135#>12.08<#1135#><#1136#>15.84<#1136#>
<#1137#>20.3<#1137#>t<#1138#>13.7<#1138#><#1139#>12.6<#1139#>
<#1140#>21.7<#1140#>t<#1141#>15.62<#1141#><#1142#>8.76<#1142#>
<#1143#>22.4<#1143#>t<#1144#>16.7<#1144#><#1145#>6.6<#1145#>
<#1146#>23.1<#1146#>t<#1147#>17.87<#1147#><#1148#>4.26<#1148#>
<#1149#>24.6<#1149#>e<#1150#>20<#1150#><#1040#>@ @
@boxa@ @skip @ plus1fil
1 1 m
<#1043#>plusm@ <#1043#>
@dscale@
@checkspec@spec
. When the gap is less than an interword space it is eliminated, and the texts are joined; when it is somewhat larger it is expanded to give it more visibility. If you want to eliminate this behavior, move the following definitions up into the main part of the file.
@widold;SPMgt;@ @parshape<#1159#>@parshape@posold@widold <#1159#>@lines<#1160#>elt<#1161#>@nline<#1161#><#1162#>@posold<#1162#><#1163#>@widold<#1163#>@lines<#1160#>@npslinesne @widold@widseg @posold@posseg
Since the processing is slow, there are some messages to say how
things are going. These can be eliminated to save space (Put a
There are also a number of parameters which can be changed to affect the size-optimisation procedure. Search for the word ;SPMquot;optimise;SPMquot;
Version 1.0 (March 1993) Initial release.
;''